package master

import (
	"crontab/common"
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"strconv"
	"time"
)

type ApiServer struct {
	httpServer *http.Server
}

//构建单例对象
var (
	G_ApiServer *ApiServer
)

//保存任务接口---到zookeeper中
func saveJob(writer http.ResponseWriter, req *http.Request) {
	var (
		err     error
		job     common.Job
		oldJob  *common.Job
		resp    []byte
		postJob string
	)
	//1.解析post表单
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	postJob = req.PostForm.Get("job")

	if err = json.Unmarshal([]byte(postJob), &job); err != nil {
		goto ERR
	}
	//保存到zk
	if oldJob, err = G_JobMgr.SaveJob(&job); err != nil {
		goto ERR
	}
	//返回正常应答,参照java的
	if resp, err = common.BuildResponse(0, "success", oldJob); err == nil {
		writer.Write(resp)
	}
	return

ERR:
	if resp, err = common.BuildResponse(-1, err.Error(), postJob); err == nil {
		writer.Write(resp)
	}

}

//删除任务接口---zookeeper中
func deleteJob(writer http.ResponseWriter, req *http.Request) {
	var (
		err error

		oldJob  *common.Job
		resp    []byte
		postJob string
	)
	//1.解析post表单，a=1&b=2...
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	postJob = req.PostForm.Get("name")

	//保存到zk
	if oldJob, err = G_JobMgr.DeleteJob(common.JOB_SVAE_PATH + "/" + postJob); err != nil {
		goto ERR
	}
	//返回正常应答,参照java的
	if resp, err = common.BuildResponse(0, "success", oldJob); err == nil {
		writer.Write(resp)
	}
	return

ERR:
	if resp, err = common.BuildResponse(-1, err.Error(), oldJob); err == nil {
		writer.Write(resp)
	}

}

//强制杀死某个任务
func killJob(writer http.ResponseWriter, req *http.Request) {
	var (
		err error

		resp    []byte
		postJob string
	)
	//1.解析post表单，a=1&b=2...
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	postJob = req.PostForm.Get("name")

	//保存到zk
	if err = G_JobMgr.KillJob(postJob); err != nil {
		goto ERR
	}
	//返回正常应答,参照java的
	if resp, err = common.BuildResponse(0, "success", ""); err == nil {
		writer.Write(resp)
	}
	return

ERR:
	if resp, err = common.BuildResponse(-1, err.Error(), ""); err == nil {
		writer.Write(resp)
	}

}

//显示任务接口---zookeeper中
func listJob(writer http.ResponseWriter, req *http.Request) {
	var (
		err           error
		cnt           int
		jobList       []*common.Job
		resultList    *common.JobList
		resp          []byte
		offset, limit int
	)
	//1.解析post表单，a=1&b=2...
	if err = req.ParseForm(); err != nil {
		goto ERR
	}

	if offset, err = strconv.Atoi(req.PostForm.Get("offset")); err != nil {
		offset = 1
	}
	if limit, err = strconv.Atoi(req.PostForm.Get("limit")); err != nil {
		limit = 10
	}

	//保存到zk
	jobList, cnt, err = G_JobMgr.ListJob(req.PostForm.Get("path"), offset, limit)
	resultList = &common.JobList{
		JobList:     jobList,
		JobTotalNum: cnt,
	}
	if err != nil {
		goto ERR
	}
	//返回正常应答,参照java的
	if resp, err = common.BuildResponse(0, "success", resultList); err == nil {
		writer.Write(resp)
	}
	return

ERR:
	if resp, err = common.BuildResponse(-1, err.Error(), resultList); err == nil {
		writer.Write(resp)
	}

}
func listLog(writer http.ResponseWriter, req *http.Request) {
	var (
		err error

		resp      []byte
		jobName   string //任务名字
		skipParam string
		limitPara string
		skip      int
		limit     int
		logArr    []*common.JobLog
	)
	//1.解析post表单，a=1&b=2...
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	jobName = req.PostForm.Get("name")
	if jobName == "" {
		jobName = "jboo"
	}
	skipParam = req.PostForm.Get("skip")
	limitPara = req.PostForm.Get("limit")
	if skip, err = strconv.Atoi(skipParam); err != nil {
		skip = 0
	}

	if limit, err = strconv.Atoi(limitPara); err != nil {
		limit = 20
	}
	//返回正常应答,参照java的
	if logArr, err = G_LogMgr.ListLog(jobName, skip, limit); err != nil {
		goto ERR
	}
	if resp, err = common.BuildResponse(0, "", logArr); err == nil {
		writer.Write(resp)
	}
	fmt.Println(logArr)
	return
ERR:
	if resp, err = common.BuildResponse(-1, err.Error(), ""); err == nil {
		writer.Write(resp)
	}
	return
}

func workList(writer http.ResponseWriter, req *http.Request) {
	var (
		err error

		resp []byte

		workers []string
	)
	//1.解析post表单，a=1&b=2...
	if err = req.ParseForm(); err != nil {
		goto ERR
	}

	//返回正常应答,参照java的
	if workers, err = G_WorkerMgr.ListWorkers(); err != nil {
		goto ERR
	}
	if resp, err = common.BuildResponse(0, "", workers); err == nil {
		writer.Write(resp)
	}
	return
ERR:
	if resp, err = common.BuildResponse(-1, err.Error(), ""); err == nil {
		writer.Write(resp)
	}
	return
}
func InitApiServer() error {
	var (
		mux           *http.ServeMux
		staticDir     http.Dir
		staticHandler http.Handler
	)
	//配置路由
	mux = http.NewServeMux()
	mux.HandleFunc("/job/save", saveJob)
	mux.HandleFunc("/job/delete", deleteJob)
	mux.HandleFunc("/job/list", listJob)
	mux.HandleFunc("/job/kill", killJob)
	mux.HandleFunc("/job/log", listLog)
	mux.HandleFunc("/worker/list", workList)
	//加载静态文件目录
	staticDir = http.Dir(G_Config.WebRoot)
	staticHandler = http.FileServer(staticDir)
	/*
		url匹配规则是按照最长前缀来进行匹配的，当/index.html时候，就会有问题，所以使用stripprefix将前面的/给去掉然后再进行拼接==./web/index.html
	*/
	mux.Handle("/", http.StripPrefix("/", staticHandler))
	//启动监听端口
	listener, err := net.Listen("tcp", ":"+strconv.Itoa(G_Config.ApiPort))
	if err != nil {
		fmt.Println(err)
		return err
	}
	//创建一个http服务
	httpServer := &http.Server{
		ReadTimeout:  time.Duration(G_Config.ApiReadTimeout) * time.Millisecond,
		WriteTimeout: time.Duration(G_Config.ApiWriteTimeout) * time.Millisecond,
		Handler:      mux,
	}
	G_ApiServer = &ApiServer{
		httpServer: httpServer,
	}
	//启动服务端
	go httpServer.Serve(listener)
	return nil
}
